<?php
namespace org\copperforest\oak\resources\factories;
/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

class ResponseFactory 
{
    protected $config;
    protected $backtrace;
    protected $authorizedClass;
    
        
    //When is called from a Collection
    public function fetchArray( $string='', $num = 10, $page = 1, $order = array(), $group = null, &$count=null ) {
        return array();
    }
 
    public function fetchInstance( $id = null ) {
        if( !empty( $this->authorizedClass ) ) {
            $response = new $this->authorizedClass();
            $response->id = $id;
            return $response;
        }
        else {
            throw new \org\copperforest\oak\http\exceptions\ForbiddenException();
        }
    }
    
    function setConfiguration( $cnf, $backtrace=array() ){
        
        $this->backtrace = $backtrace;

        //Aqui config solo tendrá las authorizedClasses;
        $newConfiguration = array( 'AuthorizedResponses' => array() );

        foreach( $cnf[ 'AuthorizedResponses' ] as $class => $authorization ){

            $authorization[ 'Glue' ] = ( isset( $authorization[ 'Glue' ] ) ? $authorization[ 'Glue' ] : '/' );
            $appendGlue = false;
            $entero = true;
            $chunk = '';
            
            if( !empty( $authorization[ 'AuthorizedString' ] ) ){
                
                foreach( $authorization['AuthorizedString'] as $typeValue ){

                    
                    if( $typeValue[ 0 ] == 'Text' ){
                        $chunk .= ( $appendGlue ? $authorization[ 'Glue' ] : '' ) . $typeValue[ 1 ];
                        
                        if( !$appendGlue ){
                            $appendGlue = true;
                        }
                    }
                    else if( $typeValue[ 0 ] == 'BacktraceId' ){
                        $chunk .=  ( $appendGlue ? $authorization[ 'Glue' ] : '' ) . implode( $authorization[ 'Glue' ], $this->backtrace[ (int) $typeValue[ 1 ] ]->id );
                        
                        if( !$appendGlue ){
                            $appendGlue = true;
                        }
                    }
                    else{
                        $entero = false;
                        $appendGlue = false;
                         
                        if( !empty( $chunk ) && !$this->appendChunk( $authorization, $class, $newConfiguration, $chunk ) ){
                            continue 2;
                        }

                        $newConfiguration[ 'AuthorizedResponses' ][ $class ][ 'AuthorizedString' ][] = $typeValue;
                    }
                }
                
                
                if( !empty( $chunk ) && ! $this->appendChunk( $authorization, $class, $newConfiguration, $chunk ) ){
                    continue;
                }
                
                if( $entero ){
                    $this->authorizedClass = $class;
                    break;
                }
            }
            else{
                $this->authorizedClass = $class;
                break;
            }
        }
        
        $this->config = $newConfiguration;
    }
    
    private function appendChunk( $authorization, $class, &$newConfiguration, &$chunk )
    {
        
        if( !isset( $newConfiguration[ 'AuthorizedResponses' ][ $class ] ) ){
            
            $newConfiguration[ 'AuthorizedResponses' ][ $class ] = array(
                'AuthorizedString'=>array(),
                'Glue' =>  (string) $authorization[ 'Glue' ],
                'Groups' => $_SESSION->getGroups()
            );
            
        }
        
        $groups = $newConfiguration[ 'AuthorizedResponses' ][ $class ][ 'Groups' ];
        
        
        $posible = false;
        $posibleGroups = array();

        //debería ser con strpos del chunk en el grupo
        foreach( $groups as $g => $levels ){
            if( strpos( $g, $chunk ) !== false && ( empty( $authorization[ 'SecurityLevel' ] ) || in_array( $authorization[ 'SecurityLevel' ], $levels ) ) ){
                $posible = true;
                $posibleGroups[ $g ] = $levels;
            }
        }
                
        //Si no es seleccionable tengo que hacer un continue 2!!!   
        if( !$posible ){
            unset( $newConfiguration[ 'AuthorizedResponses' ][ $class ] );
            return false;
        }
        
        $newConfiguration[ 'AuthorizedResponses' ][ $class ]['AuthorizedString'][] = array( 'Text', $chunk );
        $newConfiguration[ 'AuthorizedResponses' ][ $class ][ 'Groups' ] = $posibleGroups;
        
        $chunk='';
        return true;
    }
    
    
    static function parseFactory( \SimpleXMLElement $xml ){

        $config = array( 'AuthorizedResponses' => array(), 'Query' => null );
        
        if( isset( $xml->AuthorizedClass[ 1 ] ) ) {
            foreach( $xml->AuthorizedClass as $c ) {
                
                $glue = '/';
                if( !empty( $c->AuthorizedString[ 'Glue' ] ) ) {
                    $glue =  (string) $c->AuthorizedString[ 'Glue' ];
                }
                $level = null;
                if( !empty( $c->AuthorizedString[ 'SecurityLevel' ] ) ) {
                    $level =  (string) $c->AuthorizedString[ 'SecurityLevel' ];
                }
                

                $config[ 'AuthorizedResponses' ][ (string) $c->FullyQualifiedName ] = array( 'Glue' => $glue, 'AuthorizedString' => array(), 'SecurityLevel' => $level );
                
                foreach(  $c->children() as $child ) {                    
                   $config[ 'AuthorizedResponses' ][ (string) $c->FullyQualifiedName ][ 'AuthorizedString' ][] = array( $child->getName(), (string) $child );
                }
                
            }
        }
        else {
            $glue = '/';
            if( !empty( $xml->AuthorizedClass->AuthorizedString[ 'Glue' ] ) ) {
                $glue =  (string) $xml->AuthorizedClass->AuthorizedString[ 'Glue' ];
            }
            
            $level = null;
            if( !empty( $xml->AuthorizedClass->AuthorizedString[ 'SecurityLevel' ] ) ) {
                $level =  (string) $xml->AuthorizedClass->AuthorizedString[ 'SecurityLevel' ];
            }
        
            $config[ 'AuthorizedResponses' ][  (string) $xml->AuthorizedClass->FullyQualifiedName ] = array( 'Glue' => $glue, 'AuthorizedString' => array() , 'SecurityLevel' => $level );
            
            if( isset ($xml->AuthorizedClass->AuthorizedString) ) {
                
                foreach( $xml->AuthorizedClass->AuthorizedString->children() as $child ) {
                    $config[ 'AuthorizedResponses' ][ (string) $xml->AuthorizedClass->FullyQualifiedName ][ 'AuthorizedString' ][] = array( $child->getName(), (string) $child );
                }
            }
        }
        
        return $config;
    }

    
}